﻿using MiniFox.Components;
using MiniFox.Log;
using MiniFox.Tasks.Providers;
using System.Collections.ObjectModel;

namespace MiniFox.Tasks
{
    internal static class TaskPool
    {
        static readonly object initializeLocker;
        static readonly object taskListAccessLocker;
        static readonly object providerLocker;

        static bool hasInitialied;
        static TaskItemProvider provider;
        static TaskPool()
        {
            hasInitialied = false;
            initializeLocker = new object();
            taskListAccessLocker = new object();
            providerLocker = new object();
        }

        internal static TaskItemProvider CurrentTaskItemProvider
        {
            get
            {
                lock (providerLocker)
                {
                    if (provider == null)
                    {
                        if (ComponentFactory.IsRegistered<TaskItemProvider>())
                            provider = ComponentFactory.GetComponent<TaskItemProvider>();
                        else
                            provider = new DefaultTaskItemProvider();
                    }
                }
                return provider;
            }
        }

        internal static void StartTask(string name)
        {
            var task = TaskList[name];
            task.Start();
        }

        internal static void StopTask(string name)
        {
            var task = TaskList[name];
            task.Stop();
        }

        internal static void Initialize(ILogger logger)
        {
            if (hasInitialied)
                return;
            lock (initializeLocker)
            {
                if (TaskList.Count > 0)
                {
                    //中止所有现有任务
                    StopAllTasks();
                    //清空任务池
                    TaskList.Clear();
                }
                try
                {
                    TaskItem[] taskitems = CurrentTaskItemProvider.LoadTaskItems();
                    if (taskitems != null && taskitems.Length > 0)
                    {
                        foreach (TaskItem item in taskitems)
                        {
                            Add(item);
                        }
                    }
                }
                catch 
                {
                    //logger.WriteError();
                }

                hasInitialied = true;
            }
        }
        internal static void StartAllTasks()
        {
            foreach (TaskItem taskItem in TaskList)
            {
                taskItem.Start();
            }
        }
        internal static void StopAllTasks()
        {
            foreach (TaskItem taskItem in TaskList)
            {
                taskItem.Stop();
            }
        }
        internal static void Add(TaskItem taskItem, bool autoStart = false)
        {
            TaskList.Add(taskItem);
            if (autoStart)
                taskItem.Start();
        }
        internal static void Remove(string name)
        {
            TaskItem taskItem = TaskList[name];
            taskItem.Stop();
            TaskList.Remove(name);
        }
        static TaskItemCollection _taskList;
        internal static TaskItemCollection TaskList
        {
            get
            {
                lock (taskListAccessLocker)
                {
                    if (_taskList == null)
                        _taskList = new TaskItemCollection();
                }
                return _taskList;
            }
        }
    }

    internal class TaskItemCollection : KeyedCollection<string, TaskItem>
    {
        protected override string GetKeyForItem(TaskItem item)
        {
            return item.Name;
        }
    }
}
